Skip to content

feat(wfctl): add 'plugin marketplace-verify' subcommand#725

Merged
intel352 merged 1 commit into
mainfrom
feat/wfctl-plugin-verify-1779215845
May 19, 2026
Merged

feat(wfctl): add 'plugin marketplace-verify' subcommand#725
intel352 merged 1 commit into
mainfrom
feat/wfctl-plugin-verify-1779215845

Conversation

@intel352
Copy link
Copy Markdown
Contributor

Closes #724. Scans GoCodeAlone org wfctl.yaml files for plugin pins; suggests manifest status. Backed by gh api. 6 new unit tests cover verdict logic + URL construction + error paths.

Closes workflow#724.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 19, 2026 18:45
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new wfctl plugin marketplace verification command intended to scan GitHub-hosted wfctl.yaml files and suggest whether a plugin registry manifest should be verified or experimental.

Changes:

  • Registers wfctl plugin marketplace-verify.
  • Adds GitHub CLI-backed code search and JSON/human-readable reporting.
  • Adds unit tests for search verdict behavior, URL construction, and error paths.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
cmd/wfctl/plugin.go Adds the new plugin subcommand to dispatch and usage output.
cmd/wfctl/plugin_marketplace_verify.go Implements marketplace verification, GitHub search integration, and reporting.
cmd/wfctl/plugin_marketplace_verify_test.go Adds tests for search results, errors, escaping, and endpoint construction.

Comment on lines +93 to +97
// searchOrgForPluginPins queries the GitHub code-search API for `name:
// <plugin>` occurrences inside wfctl.yaml files within the org. Returns a
// list of repo+path strings.
func searchOrgForPluginPins(ctx context.Context, org, plugin string, ghAPI func(context.Context, string) ([]byte, error)) ([]string, error) {
query := fmt.Sprintf(`filename:wfctl.yaml org:%s "name: workflow-plugin-%s"`, org, plugin)
Comment on lines +20 to +24
fs := flag.NewFlagSet("plugin verify", flag.ContinueOnError)
org := fs.String("org", "GoCodeAlone", "GitHub org to scan")
jsonOut := fs.Bool("json", false, "Output JSON instead of human-readable text")
fs.Usage = func() {
fmt.Fprintf(fs.Output(), `Usage: wfctl plugin verify [options] <plugin-name>
@intel352 intel352 merged commit e7deee4 into main May 19, 2026
24 of 25 checks passed
@intel352 intel352 deleted the feat/wfctl-plugin-verify-1779215845 branch May 19, 2026 18:49
@github-actions
Copy link
Copy Markdown

⏱ Benchmark Results

No significant performance regressions detected.

benchstat comparison (baseline → PR)
## benchstat: baseline → PR
baseline-bench.txt:274: parsing iteration count: invalid syntax
baseline-bench.txt:349214: parsing iteration count: invalid syntax
baseline-bench.txt:637566: parsing iteration count: invalid syntax
baseline-bench.txt:918025: parsing iteration count: invalid syntax
baseline-bench.txt:1219277: parsing iteration count: invalid syntax
baseline-bench.txt:1514166: parsing iteration count: invalid syntax
benchmark-results.txt:274: parsing iteration count: invalid syntax
benchmark-results.txt:353360: parsing iteration count: invalid syntax
benchmark-results.txt:682524: parsing iteration count: invalid syntax
benchmark-results.txt:982003: parsing iteration count: invalid syntax
benchmark-results.txt:1279895: parsing iteration count: invalid syntax
benchmark-results.txt:1574895: parsing iteration count: invalid syntax
goos: linux
goarch: amd64
pkg: github.com/GoCodeAlone/workflow/dynamic
cpu: AMD EPYC 7763 64-Core Processor                
                            │ baseline-bench.txt │       benchmark-results.txt        │
                            │       sec/op       │    sec/op     vs base              │
InterpreterCreation-4              10.361m ± 70%   8.222m ± 61%       ~ (p=0.699 n=6)
ComponentLoad-4                     3.659m ±  1%   3.549m ±  1%  -3.00% (p=0.002 n=6)
ComponentExecute-4                  1.964µ ±  1%   1.916µ ±  1%  -2.44% (p=0.002 n=6)
PoolContention/workers-1-4          1.092µ ±  3%   1.089µ ±  2%       ~ (p=0.623 n=6)
PoolContention/workers-2-4          1.080µ ±  1%   1.065µ ±  2%       ~ (p=0.100 n=6)
PoolContention/workers-4-4          1.093µ ±  1%   1.062µ ±  0%  -2.84% (p=0.002 n=6)
PoolContention/workers-8-4          1.091µ ±  2%   1.070µ ±  1%  -1.92% (p=0.002 n=6)
PoolContention/workers-16-4         1.094µ ±  4%   1.065µ ±  5%  -2.65% (p=0.041 n=6)
ComponentLifecycle-4                3.649m ±  1%   3.554m ±  0%  -2.60% (p=0.002 n=6)
SourceValidation-4                  2.334µ ±  1%   2.279µ ±  2%  -2.38% (p=0.004 n=6)
RegistryConcurrent-4                796.9n ±  4%   772.5n ±  2%  -3.06% (p=0.009 n=6)
LoaderLoadFromString-4              3.653m ±  0%   3.566m ±  0%  -2.40% (p=0.002 n=6)
geomean                             19.40µ         18.63µ        -3.95%

                            │ baseline-bench.txt │        benchmark-results.txt         │
                            │        B/op        │     B/op      vs base                │
InterpreterCreation-4               2.027Mi ± 0%   2.027Mi ± 0%       ~ (p=0.922 n=6)
ComponentLoad-4                     2.180Mi ± 0%   2.180Mi ± 0%       ~ (p=0.509 n=6)
ComponentExecute-4                  1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-1-4          1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-2-4          1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-4-4          1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-8-4          1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-16-4         1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
ComponentLifecycle-4                2.183Mi ± 0%   2.183Mi ± 0%       ~ (p=0.554 n=6)
SourceValidation-4                  1.984Ki ± 0%   1.984Ki ± 0%       ~ (p=1.000 n=6) ¹
RegistryConcurrent-4                1.133Ki ± 0%   1.133Ki ± 0%       ~ (p=1.000 n=6) ¹
LoaderLoadFromString-4              2.182Mi ± 0%   2.182Mi ± 0%       ~ (p=0.920 n=6)
geomean                             15.25Ki        15.25Ki       -0.00%
¹ all samples are equal

                            │ baseline-bench.txt │        benchmark-results.txt        │
                            │     allocs/op      │  allocs/op   vs base                │
InterpreterCreation-4                15.68k ± 0%   15.68k ± 0%       ~ (p=1.000 n=6)
ComponentLoad-4                      18.02k ± 0%   18.02k ± 0%       ~ (p=1.000 n=6)
ComponentExecute-4                    25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-1-4            25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-2-4            25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-4-4            25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-8-4            25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-16-4           25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
ComponentLifecycle-4                 18.07k ± 0%   18.07k ± 0%       ~ (p=1.000 n=6) ¹
SourceValidation-4                    32.00 ± 0%    32.00 ± 0%       ~ (p=1.000 n=6) ¹
RegistryConcurrent-4                  2.000 ± 0%    2.000 ± 0%       ~ (p=1.000 n=6) ¹
LoaderLoadFromString-4               18.06k ± 0%   18.06k ± 0%       ~ (p=1.000 n=6) ¹
geomean                               183.3         183.3       +0.00%
¹ all samples are equal

pkg: github.com/GoCodeAlone/workflow/middleware
                                  │ baseline-bench.txt │       benchmark-results.txt       │
                                  │       sec/op       │   sec/op     vs base              │
CircuitBreakerDetection-4                  287.9n ± 0%   287.9n ± 4%       ~ (p=0.981 n=6)
CircuitBreakerExecution_Success-4          21.43n ± 1%   21.54n ± 1%       ~ (p=0.177 n=6)
CircuitBreakerExecution_Failure-4          66.22n ± 0%   66.14n ± 0%       ~ (p=0.327 n=6)
geomean                                    74.21n        74.31n       +0.14%

                                  │ baseline-bench.txt │       benchmark-results.txt        │
                                  │        B/op        │    B/op     vs base                │
CircuitBreakerDetection-4                 144.0 ± 0%     144.0 ± 0%       ~ (p=1.000 n=6) ¹
CircuitBreakerExecution_Success-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
CircuitBreakerExecution_Failure-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                              ²               +0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

                                  │ baseline-bench.txt │       benchmark-results.txt        │
                                  │     allocs/op      │ allocs/op   vs base                │
CircuitBreakerDetection-4                 1.000 ± 0%     1.000 ± 0%       ~ (p=1.000 n=6) ¹
CircuitBreakerExecution_Success-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
CircuitBreakerExecution_Failure-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                              ²               +0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/module
                                 │ baseline-bench.txt │       benchmark-results.txt        │
                                 │       sec/op       │    sec/op     vs base              │
IaCStateBackend_InProcess-4              309.2n ± 30%   304.3n ± 28%       ~ (p=0.165 n=6)
IaCStateBackend_GRPC-4                   9.735m ±  2%   9.346m ±  3%  -4.00% (p=0.002 n=6)
JQTransform_Simple-4                     680.2n ± 44%   658.5n ± 42%       ~ (p=0.240 n=6)
JQTransform_ObjectConstruction-4         1.655µ ±  1%   1.532µ ±  1%  -7.40% (p=0.002 n=6)
JQTransform_ArraySelect-4                3.640µ ±  1%   3.480µ ±  0%  -4.40% (p=0.002 n=6)
JQTransform_Complex-4                    40.38µ ±  4%   39.12µ ±  1%  -3.11% (p=0.002 n=6)
JQTransform_Throughput-4                 2.048µ ±  2%   1.862µ ±  1%  -9.06% (p=0.002 n=6)
SSEPublishDelivery-4                     63.62n ±  0%   63.91n ±  7%       ~ (p=0.143 n=6)
geomean                                  3.995µ         3.832µ        -4.08%

                                 │ baseline-bench.txt │        benchmark-results.txt         │
                                 │        B/op        │     B/op      vs base                │
IaCStateBackend_InProcess-4              416.0 ± 0%       416.0 ± 0%       ~ (p=1.000 n=6) ¹
IaCStateBackend_GRPC-4                 5.906Mi ± 9%     5.895Mi ± 8%       ~ (p=0.937 n=6)
JQTransform_Simple-4                   1.273Ki ± 0%     1.273Ki ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_ObjectConstruction-4       1.773Ki ± 0%     1.773Ki ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_ArraySelect-4              2.625Ki ± 0%     2.625Ki ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_Complex-4                  16.22Ki ± 0%     16.22Ki ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_Throughput-4               1.984Ki ± 0%     1.984Ki ± 0%       ~ (p=1.000 n=6) ¹
SSEPublishDelivery-4                     0.000 ± 0%       0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                             ²                 -0.02%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

                                 │ baseline-bench.txt │        benchmark-results.txt        │
                                 │     allocs/op      │  allocs/op   vs base                │
IaCStateBackend_InProcess-4              2.000 ± 0%      2.000 ± 0%       ~ (p=1.000 n=6) ¹
IaCStateBackend_GRPC-4                  6.836k ± 0%     6.830k ± 0%       ~ (p=0.327 n=6)
JQTransform_Simple-4                     10.00 ± 0%      10.00 ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_ObjectConstruction-4         15.00 ± 0%      15.00 ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_ArraySelect-4                30.00 ± 0%      30.00 ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_Complex-4                    324.0 ± 0%      324.0 ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_Throughput-4                 17.00 ± 0%      17.00 ± 0%       ~ (p=1.000 n=6) ¹
SSEPublishDelivery-4                     0.000 ± 0%      0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                             ²                -0.01%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/schema
                                    │ baseline-bench.txt │       benchmark-results.txt        │
                                    │       sec/op       │    sec/op     vs base              │
SchemaValidation_Simple-4                    1.116µ ± 7%   1.095µ ± 27%       ~ (p=0.260 n=6)
SchemaValidation_AllFields-4                 1.686µ ± 5%   1.671µ ±  8%       ~ (p=0.485 n=6)
SchemaValidation_FormatValidation-4          1.578µ ± 1%   1.576µ ±  1%       ~ (p=0.734 n=6)
SchemaValidation_ManySchemas-4               1.873µ ± 4%   1.847µ ±  2%       ~ (p=0.240 n=6)
geomean                                      1.535µ        1.519µ        -1.07%

                                    │ baseline-bench.txt │       benchmark-results.txt        │
                                    │        B/op        │    B/op     vs base                │
SchemaValidation_Simple-4                   0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_AllFields-4                0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_FormatValidation-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_ManySchemas-4              0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                                ²               +0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

                                    │ baseline-bench.txt │       benchmark-results.txt        │
                                    │     allocs/op      │ allocs/op   vs base                │
SchemaValidation_Simple-4                   0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_AllFields-4                0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_FormatValidation-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_ManySchemas-4              0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                                ²               +0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/store
                                   │ baseline-bench.txt │        benchmark-results.txt        │
                                   │       sec/op       │    sec/op     vs base               │
EventStoreAppend_InMemory-4                1.280µ ± 13%   1.160µ ± 21%        ~ (p=0.310 n=6)
EventStoreAppend_SQLite-4                  1.360m ±  2%   1.277m ±  3%   -6.11% (p=0.002 n=6)
GetTimeline_InMemory/events-10-4           14.87µ ±  4%   13.47µ ±  4%   -9.40% (p=0.002 n=6)
GetTimeline_InMemory/events-50-4           73.88µ ± 13%   74.29µ ±  4%        ~ (p=1.000 n=6)
GetTimeline_InMemory/events-100-4          133.7µ ±  1%   150.0µ ±  5%  +12.16% (p=0.002 n=6)
GetTimeline_InMemory/events-500-4          680.7µ ±  2%   629.7µ ±  1%   -7.50% (p=0.002 n=6)
GetTimeline_InMemory/events-1000-4         1.402m ±  2%   1.283m ±  6%   -8.47% (p=0.002 n=6)
GetTimeline_SQLite/events-10-4             113.6µ ±  2%   105.9µ ±  1%   -6.77% (p=0.002 n=6)
GetTimeline_SQLite/events-50-4             264.1µ ±  5%   245.5µ ±  0%   -7.05% (p=0.002 n=6)
GetTimeline_SQLite/events-100-4            452.8µ ±  2%   417.7µ ±  4%   -7.76% (p=0.002 n=6)
GetTimeline_SQLite/events-500-4            1.990m ±  3%   1.766m ±  2%  -11.27% (p=0.002 n=6)
GetTimeline_SQLite/events-1000-4           3.872m ±  2%   3.429m ±  2%  -11.44% (p=0.002 n=6)
geomean                                    233.0µ         218.5µ         -6.22%

                                   │ baseline-bench.txt │        benchmark-results.txt         │
                                   │        B/op        │     B/op      vs base                │
EventStoreAppend_InMemory-4                  790.5 ± 8%     791.0 ± 6%       ~ (p=0.738 n=6)
EventStoreAppend_SQLite-4                  1.983Ki ± 2%   1.986Ki ± 3%       ~ (p=0.504 n=6)
GetTimeline_InMemory/events-10-4           7.953Ki ± 0%   7.953Ki ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-50-4           46.62Ki ± 0%   46.62Ki ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-100-4          94.48Ki ± 0%   94.48Ki ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-500-4          472.8Ki ± 0%   472.8Ki ± 0%       ~ (p=0.567 n=6)
GetTimeline_InMemory/events-1000-4         944.3Ki ± 0%   944.3Ki ± 0%  +0.00% (p=0.022 n=6)
GetTimeline_SQLite/events-10-4             16.74Ki ± 0%   16.74Ki ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-50-4             87.14Ki ± 0%   87.14Ki ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-100-4            175.4Ki ± 0%   175.4Ki ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-500-4            846.1Ki ± 0%   846.1Ki ± 0%  -0.00% (p=0.002 n=6)
GetTimeline_SQLite/events-1000-4           1.639Mi ± 0%   1.639Mi ± 0%  +0.00% (p=0.002 n=6)
geomean                                    67.35Ki        67.36Ki       +0.02%
¹ all samples are equal

                                   │ baseline-bench.txt │        benchmark-results.txt        │
                                   │     allocs/op      │  allocs/op   vs base                │
EventStoreAppend_InMemory-4                  7.000 ± 0%    7.000 ± 0%       ~ (p=1.000 n=6) ¹
EventStoreAppend_SQLite-4                    53.00 ± 0%    53.00 ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-10-4             125.0 ± 0%    125.0 ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-50-4             653.0 ± 0%    653.0 ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-100-4           1.306k ± 0%   1.306k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-500-4           6.514k ± 0%   6.514k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-1000-4          13.02k ± 0%   13.02k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-10-4               382.0 ± 0%    382.0 ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-50-4              1.852k ± 0%   1.852k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-100-4             3.681k ± 0%   3.681k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-500-4             18.54k ± 0%   18.54k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-1000-4            37.29k ± 0%   37.29k ± 0%       ~ (p=1.000 n=6) ¹
geomean                                     1.162k        1.162k       +0.00%
¹ all samples are equal

Benchmarks run with go test -bench=. -benchmem -count=6.
Regressions ≥ 20% are flagged. Results compared via benchstat.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 19, 2026

Codecov Report

❌ Patch coverage is 34.56790% with 53 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
cmd/wfctl/plugin_marketplace_verify.go 34.61% 51 Missing ⚠️
cmd/wfctl/plugin.go 33.33% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(wfctl): plugin verify subcommand for status promotion

2 participants